#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include "../UniApoLib/SDSFile.h"

using namespace std;

/*
 *
 */
int main(int argc, char **argv) {
    if (argc >> 3) {
        cerr << "ERROR (SDS File Editor): ";
        cerr << "Requires at least two arguments" << endl;
        return 1;
    }
    void processLine(string const & lineData);
    string option = argv[1];
    string file = argv[2];
    string filename = file.substr(0, file.size() - 4);
    string extension = file.substr(file.size() - 4, file.size());

    //First we check if a correct filename was supplied
    if (extension != ".SDS") {
        cerr << "ERROR in extension (SDS File Editor):";
        cerr << " Expected filename.SDS extension" << endl;
        return 3;
    }
    //Next we check if the option format supplied is correct
    //If the size of the argument (which must be 2) is incorrect
    //or the argument does not start with '-'
    if ((option.size() != 2) || (option.at(0) != '-')) {
        cerr << "ERROR in 1st argument (SDS File Editor): Use -n for new file,";
        cerr << " -o for open existing file, -c to convert csv file";
        cerr << " or -d to delete a file." << endl;
        return 2;
    }

    char coption = option.at(1); //operation argument
    //Creating empty SDS object and SDSFile path for later
    SDSFile SDS;
    SDS.name(filename);

    switch (coption) {
        case 'n':

        {
            if (argc != 3) {
                cerr << "ERROR (SDS File Editor): Requires 2 arguments" << endl;
                return 1;
            }
            //This saves the file in SDS
            SDS.buildFile();
            cout << "New SDS file created" << endl;

        }
            break;

        case 'o':
        {
            if (argc != 3) {
                cerr << "ERROR (SDS File Editor): Requires 2 arguments" << endl;
                return 1;
            }

            cout << "Open Existing File" << endl;
            SDS.loadFile();
            cout << "Select Section" << endl;
        }
            break;
        case 'd':
        {
            //are you sure?
            string confirm;
            while ((confirm != "y") || (confirm != "n")) {
                cout << "Are you sure?(y/n): " << endl;
                getline(cin, confirm);
                if (confirm == "n") {
                    return 0;
                }
                if (confirm == "y") {
                    if (remove(SDS.getPath().c_str()) != 0) {
                        cerr << "ERROR (SDS File Editor): No such file" << endl;
                        return 4;
                    } else
                        cout << "File deleted" << endl;
                    break;
                }
            }
        }
            break;
        default:
        {
            cerr << "ERROR (SDS File Editor): " << endl;
            cerr << "1st argument must be -n for new file";
            cerr << "-o for open existing file or -d to delete a file" << endl;
            return 2;
        }
            break;
    }
    string imod;
    while (imod != "q") {


        cout << "Enter command (g,l,d,c,q,s or h for help): ";
        getline(cin, imod);
        if (imod == "h") {
            cout << "---SDSEditor Help---" << endl;
            cout << "Type g to modify static (or global) data" << endl;
            cout << "Type l to modify dynamic (or local) header" << endl;
            cout << "Type d to modify dynamic data" << endl;
            cout << "Type c to convert a csv file in SDS format" << endl;
            cout << "Type s to save and q to quit" << endl;
        }
        if (imod == "s") {
            cout << "saving:" << SDS.getPath() << endl;
            SDS.buildFile();
            cout << "file saved" << endl;
        }
        if (imod == "g") {
            string gmod;
            cout << "Static Data Editor" << endl;
            while (gmod != "q") {
                SDS.printStatic();
                cout << "Enter command (a,m,d,q,s or h for help): ";
                getline(cin, gmod);
                if (gmod == "s") {
                    cout << "saving" << endl;
                    SDS.buildFile();
                    cout << "file saved" << endl;
                }
                if (gmod == "a") {
                    string attrib;
                    string val;
                    string stbl;
                    string satrb;
                    cout << "Enter Attribute Name: ";
                    getline(cin, attrib);
                    cout << "Enter Value: ";
                    getline(cin, val);
                    cout << "Enter Source Table: ";
                    getline(cin, stbl);
                    cout << "Enter Source Attribute: ";
                    getline(cin, satrb);

                    if ((attrib == "") || (val == "")) {
                        cerr << "Entering Attribute name and value";
                        cerr << "is mandatory" << endl;
                        return 8;
                    }
                    if (stbl == "") {
                        stbl = "@VOID@";
                    }
                    if (satrb == "") {
                        satrb = "@VOID";
                    }

                    SDS.addStatic(attrib, val, stbl, satrb);
                    
                }

                if (gmod == "m") {
                    string attrib;
                    string val;
                    string stbl;
                    string satrb;
                    int entryNo;
                    string xline;
                    cout << "Enter entry number: ";
                    getline(cin, xline);

                    stringstream ss(xline);
                    ss >> entryNo;
                    cout << "Enter Attribute Name: ";
                    getline(cin, attrib);
                    cout << "Enter Value: ";
                    getline(cin, val);
                    cout << "Enter Source Table: ";
                    getline(cin, stbl);
                    cout << "Enter Source Attribute: ";
                    getline(cin, satrb);

                    if ((attrib == "") || (val == "")) {
                        cerr << "Entering Attribute name and value";
                        cerr << "is mandatory" << endl;
                        return 8;
                    }
                    if (stbl == "") {
                        stbl = "@VOID@";
                    }
                    if (satrb == "") {
                        satrb = "@VOID";
                    }

                    SDS.modifyStatic(attrib, val, stbl, satrb, entryNo);
                  
                }

                if (gmod == "d") {

                    int entryNo;
                    string xline;
                    cout << "Enter entry number: ";
                    getline(cin, xline);
                    stringstream ss(xline);
                    ss >> entryNo;

                    SDS.removeStatic(entryNo);
                   
                }
            }
        }

        if (imod == "l") {
            string lmod;
            cout << "Dynamic Data Header Editor" << endl;
            while (lmod != "q") {
                SDS.printHeader();
                cout << "Enter command (a,i,m,d,x,q,s or h for help): ";
                getline(cin, lmod);
                if (lmod == "h") {
                    cout << "Dynamic Data Header Editor Help" << endl;
                    cout << "a: Add a component" << endl;
                    cout << "i: Insert a component" << endl;
                    cout << "m: Modify component data" << endl;
                    cout << "d: delete component" << endl;
                    cout << "x: set datastring component" << endl;
                }
                if (lmod == "s") {
                    cout << "saving" << endl;
                    SDS.buildFile();
                    cout << "file saved" << endl;
                }
                if (lmod == "a") {

                    string attrib;
                    string stbl;
                    string satrb;
                    cout << "Enter Attribute Name: ";
                    getline(cin, attrib);
                    cout << "Enter Source Table: ";
                    getline(cin, stbl);
                    cout << "Enter Source Attribute: ";
                    getline(cin, satrb);

                    if (attrib == "") {
                        cerr << "Entering attribute name";
                        cerr << "is mandatory" << endl;
                        return 8;
                    }
                    if (stbl == "") {
                        stbl = "@VOID@";
                    }
                    if (satrb == "") {
                        satrb = "@VOID";
                    }

                    SDS.addHeading(attrib, stbl, satrb);
                    SDS.printHeader();
                }
                if (lmod == "i") {
                    string attrib;
                    string stbl;
                    string satrb;
                    int entryNo;
                    string xline;
                    cout << "Enter Component number: ";
                    getline(cin, xline);

                    stringstream ss(xline);
                    ss >> entryNo;
                    cout << "Enter Attribute Name: ";
                    getline(cin, attrib);
                    cout << "Enter Source Table: ";
                    getline(cin, stbl);
                    cout << "Enter Source Attribute: ";
                    getline(cin, satrb);

                    if (attrib == "") {
                        cerr << "Entering attribute name";
                        cerr << "is mandatory" << endl;
                        return 8;
                    }
                    if (stbl == "") {
                        stbl = "@VOID@";
                    }
                    if (satrb == "") {
                        satrb = "@VOID";
                    }

                    SDS.modifyHeading(entryNo, attrib, stbl, satrb);
               
                }

                if (lmod == "m") {
                    string attrib;
                    string stbl;
                    string satrb;
                    int entryNo;
                    string xline;
                    cout << "Enter Component number: ";
                    getline(cin, xline);

                    stringstream ss(xline);
                    ss >> entryNo;
                    cout << "Enter Attribute Name: ";
                    getline(cin, attrib);
                    cout << "Enter Source Table: ";
                    getline(cin, stbl);
                    cout << "Enter Source Attribute: ";
                    getline(cin, satrb);

                    if (attrib == "") {
                        cerr << "Entering Attribute name and value";
                        cerr << "is mandatory" << endl;
                        //return 8;
                    }
                    if (stbl == "") {
                        stbl = "@VOID@";
                    }
                    if (satrb == "") {
                        satrb = "@VOID";
                    }

                    SDS.modifyHeading(entryNo, attrib, stbl, satrb);
                    SDS.printHeader();
                }

                if (lmod == "d") {

                    int entryNo;
                    string xline;
                    cout << "Enter component number: ";
                    getline(cin, xline);
                    stringstream ss(xline);
                    ss >> entryNo;

                    SDS.removeHeading(entryNo);
                 
                }

                if (lmod == "x") {


                    SDS.addHeading("@DS@", "@VOID@", "@VOID@");
                    SDS.printHeader();

                }


            }
        }
        if (imod == "d") {
            string dmod;
            cout << "Dynamic Data Entry Editor" << endl;
            while (dmod != "q") {
                cout << "Enter command (n,c,x,a,b,i,m, d,s or h for help): ";
                getline(cin, dmod);
                if (dmod == "h") {
                    cout << "Dynamic Data Entry Editor Help" << endl;
                    cout << "n: Create empty new data entry." << endl;
                    cout << "c: Modify new data entry component." << endl;
                    cout << "x: Clear Component." << endl;
                    cout << "a: Add new entry to (end of) SDS file." << endl;
                    cout << "i: Insert new entry at a given line." << endl;
                    cout << "m: Modify entry at a given line." << endl;
                    cout << "d: Delete entry" << endl;
                    cout << "b: Bulk SDS adding using STDPLUGS" << endl;

                }
                if (dmod == "s") {
                    cout << "saving" << endl;
                    SDS.buildFile();
                    cout << "file saved" << endl;
                }

                if (dmod == "n") {
                    cout << "Creating new Data Entry: " << endl;
                    SDS.createNewEntry();
                    SDS.printTemp();
                }
                if (dmod == "c") {
                    int entryNo;
                    string xline;
                    cout << "Enter component number: ";
                    getline(cin, xline);
                    stringstream ss(xline);
                    ss >> entryNo;
                    cout << "Enter component data: ";
                    getline(cin, xline);
                    SDS.addEntryComponent(xline, entryNo);
                    cout << "New Data Entry: " << endl;
                    SDS.printTemp();
                }
                if (dmod == "x") {
                    int entryNo;
                    string xline;
                    cout << "Enter component number: ";
                    getline(cin, xline);
                    stringstream ss(xline);
                    ss >> entryNo;
                    SDS.clearEntryComponent(entryNo);
                    cout << "New Data Entry: " << endl;
                    SDS.printTemp();
                }
                if (dmod == "a") {
                    SDS.addEntry();
                    cout << "Data Entry Added To SDS File" << endl;
                    SDS.printEntries();
                }
                if (dmod == "i") {
                    int entryNo;
                    string xline;
                    cout << "Enter component number: ";
                    getline(cin, xline);
                    stringstream ss(xline);
                    ss >> entryNo;
                    SDS.addEntry(entryNo);
                    cout << "Data Entry Added To SDS File" << endl;
                    SDS.printEntries();
                }

                if (dmod == "m") {
                    int entryNo;
                    string xline;
                    cout << "Enter component number: ";
                    getline(cin, xline);
                    stringstream ss(xline);
                    ss >> entryNo;
                    SDS.modifyEntry(entryNo);
                    cout << "Data Entry Modifed" << endl;
                    SDS.printEntries();
                }

                if (dmod == "d") {
                    int entryNo;
                    string xline;
                    cout << "Enter component number: ";
                    getline(cin, xline);
                    stringstream ss(xline);
                    ss >> entryNo;
                    SDS.removeEntry(entryNo);
                    SDS.printEntries();
                }

            }

        }
    }

    return 0;
}





